

open Format
open Lexing

(* Option de compilation, pour s'arrêter à l'issue du parser *)
let parse_only = ref false
let show_pseudoCode = ref true

let ifile = ref ""
let ofile = ref ""

let set_file f s = f := s 

let options = 
	["-parse-only", Arg.Set parse_only, 
	 "	Pour ne faire uniquement que la phase d'analyse syntaxique";
	 
	 "-show-pseudoCode", Arg.Set show_pseudoCode, 
	 "	Affiche un pseudo code genere a partir de l'arbre syntaxique";
	 
	 "-o", Arg.String (set_file ofile), 
	 "<file>	Pour indiquer le mom du fichier de sortie"]
	 
let usage = "usage: arithc [option] file.exp"

let localisation pos =
  let l = pos.pos_lnum in
  let c = pos.pos_cnum - pos.pos_bol + 1 in
  eprintf "File \"%s\", line %d, characters %d-%d:\n" !ifile l (c-1) c

let () = 
	(* Parsing de la ligne de commande *)
	Arg.parse options (set_file ifile) usage;

	(* On vérifie que le nom du fichier source a bien été indiqué *)
	if !ifile="" then begin printf "Aucun fichier à compiler\n@?"; exit 1 end;
	
	if !ofile="" then ofile := Filename.chop_suffix !ifile ".exp" ^ ".s";
	
	(* Ouverture du fichier source en lecture *)
	let f = open_in !ifile in
		
	(* Création d'un tampon d'analyse lexicale *)
	let buf = Lexing.from_channel f in
	
	try
		(* Parsing: la fonction	Parser.prog transforme le tampon lexical en un 
			 arbre de syntaxe abstraite si aucune erreur (lexicale ou syntaxique) 
			 n'est détectée.
			 La fonction Lexer.token est utilisée par Parser.prog pour obtenir 
			 le prochain token. *)
		let p = Parser.fichier Lexer.token buf in
		close_in f;
		
		(* Va t'on genere et affiche un Pseudo code. *)
		if !show_pseudoCode then 
			Arbre.dessiner_programme p;
				
		(* On s'arrête ici si on ne veut faire que le parsing *)
		if !parse_only then exit 0;
		
		(* @todo Compiler *)
		
	with
		| Lexer.ErreurLexicale(c,n) -> 
	(* Erreur lexicale. On récupère sa position absolue et 
		 on la convertit en numéro de ligne *)
			eprintf "Erreur dans l'analyse lexicale ligne: %d caractere: %c@." n c;
			exit 1
		| Parsing.Parse_error -> 
	(* Erreur syntaxique. On récupère sa position absolue et on la 
		 convertit en numéro de ligne *)
		 	localisation (Lexing.lexeme_start_p buf);
			eprintf "Erreur dans l'analyse syntaxique@.";
			exit 1
		(*| Compile.VarUndef s-> 
	(* Erreur d'utilisation de variable pendant la compilation *)
	eprintf 
		"Erreur de compilation: la variable %s n'est pas définie@." s;
	exit 1*)
